#include "Flyweight.h"

#include <iostream>
using namespace std;

Flyweight::Flyweight(const STATE& state)
{
    cout << "Flyweight::Flyweight(const STATE& state)" << endl;
    _state = state;
}

Flyweight::~Flyweight()
{
    cout << "Flyweight::~Flyweight()" << endl;
}

inline STATE Flyweight::GetIntrinsicState()
{
    cout << "Flyweight::GetIntrinsicState() = " << _state << endl;
    return _state;
}

FlyweightFactory::FlyweightFactory()
{
    cout << "FlyweightFactory::FlyweightFactory()" << endl;
}

FlyweightFactory::~FlyweightFactory()
{
    cout << "FlyweightFactory::~FlyweightFactory()" << endl;
    list<Flyweight*>::iterator iter1;
    list<Flyweight*>::iterator iter2;
    list<Flyweight*>::iterator tmp;
    for (iter1 = _listFlyweight.begin(), iter2 = _listFlyweight.end(); iter1 != iter2;) {
        tmp = iter1;
        ++iter1;
        delete (*tmp);
    }

    _listFlyweight.clear();
}

Flyweight* FlyweightFactory::GetFlyweight(const STATE& key)
{
    cout << "FlyweightFactory::GetFlyweight(const STATE& key)" << endl;
    list<Flyweight*>::iterator iter1;
    list<Flyweight*>::iterator iter2;
    for (iter1 = _listFlyweight.begin(), iter2 = _listFlyweight.end(); iter1 != iter2; ++iter1) {
        if ((*iter1)->GetIntrinsicState() == key) {
            cout << "The Flyweight: " << key << " already exits." << endl;
            return (*iter1);
        }
    }

    cout << "Creating a new Flyweight: " << key << endl;
    Flyweight* flyweight = new ConcreteFlyweight(key);
    _listFlyweight.push_back(flyweight);
    return flyweight;
}

ConcreteFlyweight::ConcreteFlyweight(const STATE& state)
    : Flyweight(state)
{
    cout << "ConcreteFlyweight::ConcreteFlyweight(const STATE& state)" << endl;
}

ConcreteFlyweight::~ConcreteFlyweight()
{
    cout << "ConcreteFlyweight::~ConcreteFlyweight()" << endl;
}

void ConcreteFlyweight::Operation(STATE& ExtrinsicState)
{
    cout << "ConcreteFlyweight::Operation(STATE& ExtrinsicState)" << endl;
}
